﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Entity.Infrastructure;
using QuanLyHocPhi.Model;
using System.Data.Entity;

namespace QuanLyHocPhi.BLL
{
    /// <summary>
    /// Lớp xử lý nghiệp vụ liên quan đến sinh viên
    /// </summary>
    partial class BizLopHocPhan
    {
        #region Danh sách cột của DataTable dùng để import dữ liệu
        public const string Col_Checked = "Checked";
        public const string Col_MaSinhVien = "MaSinhVien";
        public const string Col_HoDem = "HoDem";
        public const string Col_Ten = "Ten";
        public const string Col_NgaySinh = "NgaySinh";
        public const string Col_MaLopGoc = "MaLop";
        public const string Col_TenLopGoc = "TenLopGoc";
        public const string Col_TrangThai = "TrangThai";
        #endregion

        #region Trạng thái của 1 dòng dữ liệu trong quá trình tiền xử lý trước khi import
        public const string Status_Error_LopSinhHoatChuaTonTai = "Lỗi: Lớp gốc chưa tồn tại";
        public const string Status_Error_DuLieuSinhVienChuaDayDu = "Lỗi: Thông tin chưa đầy đủ";
        public const string Status_Error_DuLieuSinhVienKhongNhatQuan = "Lỗi: Tên lớp gốc của sinh viên không nhất quán";
        public const string Status_Ready_TaoSVVaDangKy = "Có thể tạo mới + Đăng ký vào lớp học phần";
        public const string Status_Ready_DangKy = "Có thể đăng ký vào lớp học phần";
        public const string Status_Warning_SinhVienDaDangKy = "Đã tồn tại trong lớp học phần";
        #endregion

        public enum ImportPhaseDetect
        {
            Error_CauTrucBangKhongHopLe,
            Error_LopSinhHoatChuaTonTai,
            Error_DuLieuSinhVienChuaDayDu,
            Error_DuLieuSinhVienKhongNhatQuan,
            OK
        };

        /// <summary>
        /// Chuẩn hoá dữ liệu
        /// 1) Ánh xạ tên cột (Mã sinh viên → MaSinhVien, Họ đệm → HoDem, ...) nếu cần thiết.
        /// 2) Bổ sung thêm 2 cột MaLopGoc, TrangThai
        ///     + MaLopGoc: mã lớp gốc được suy từ (truong.MaTruong, TenLopGoc)
        ///     + TrangThai: trạng thái của dòng dữ liệu
        /// 3) Xử lý, tạo thông tin trạng thái cho từng dòng dữ liệu
        /// </summary>
        /// <param name="dt">Bảng dữ liệu</param>
        /// <param name="truong">Trường thành viên chứa các sinh viên</param>
        /// <returns></returns>
        internal static ImportPhaseDetect ChuanHoaDataSource(DataTable dt, Truong truong, LopHocPhan lopHocPhan)
        {
            DataColumnCollection columns = dt.Columns;

            #region Ánh xạ tên cột
            Dictionary<string, string> mapping = new Dictionary<string, string>();
            mapping.Add("Mã sinh viên", Col_MaSinhVien);
            mapping.Add("Họ đệm", Col_HoDem);
            mapping.Add("Tên", Col_Ten);
            mapping.Add("Ngày sinh", Col_NgaySinh);
            mapping.Add("Tên lớp gốc", Col_TenLopGoc);
            mapping.Add("Trạng thái", Col_TrangThai);
            foreach (string key in mapping.Keys)
                if (columns.Contains(key))
                    columns[key].ColumnName = mapping[key];
            #endregion

            #region 00. Kiểm tra cấu trúc bảng: có các cột MaSinhVien, HoDem, Ten, NgaySinh, TenLopGoc
            if (!columns.Contains(Col_MaSinhVien) ||
                    !columns.Contains(Col_HoDem) ||
                    !columns.Contains(Col_Ten) ||
                    !columns.Contains(Col_NgaySinh) ||
                    !columns.Contains(Col_TenLopGoc))
                return ImportPhaseDetect.Error_CauTrucBangKhongHopLe;
            #endregion

            #region Bổ sung cột MaLopGoc, TrangThai
            if (dt.Columns.Contains(Col_MaLopGoc) == false)
                dt.Columns.Add(Col_MaLopGoc, typeof(string));
            if (dt.Columns.Contains(Col_TrangThai) == false)
                dt.Columns.Add(Col_TrangThai, typeof(string));
            foreach (DataRow row in dt.Rows)
            {
                row[Col_MaLopGoc] = null;
                row[Col_TrangThai] = null;
            }
            #endregion

            #region 01. Kiểm tra tính hợp lệ dữ liệu: đủ thông tin MaSinhVien, HoDem, Ten, TenLopGoc
            int nDuLieuSinhVienChuaDayDu = 0;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                DataRow row = dt.Rows[i];
                string maSinhVien = Convert.ToString(row[Col_MaSinhVien]);
                string hoDem = Convert.ToString(row[Col_HoDem]);
                string ten = Convert.ToString(row[Col_Ten]);
                string tenLopGoc = Convert.ToString(row[Col_TenLopGoc]);
                if (maSinhVien.IsNullOrEmpty() ||
                    (hoDem + ten).IsNullOrEmpty() ||
                    tenLopGoc.IsNullOrEmpty())
                {
                    nDuLieuSinhVienChuaDayDu++;
                    row[Col_TrangThai] = Status_Error_DuLieuSinhVienChuaDayDu;
                }
            }

            if (nDuLieuSinhVienChuaDayDu > 0)
                return ImportPhaseDetect.Error_DuLieuSinhVienChuaDayDu;
            #endregion

            #region 02. Kiểm tra sự tồn tại của các lớp sinh hoạt
            #region var dictLop = Từ điển (TenLop.ToUpper() → MaLop)
            var lstLopInDB = (from lop in BizTruong.GetList_LopKhongChuyen(truong.MaTruong)
                              select lop).ToList();
            var dictLop = new Dictionary<string, string>();
            foreach (var lop in lstLopInDB)
                dictLop.Add(lop.TenLop.ToUpper(), lop.MaLop);
            #endregion

            #region Đánh dấu những lớp sinh hoạt chưa tồn tại trong hệ thống
            var lstUnknownClasses = new List<string>();
            foreach (DataRow row in dt.Rows)
            {
                string tenLop = row[Col_TenLopGoc].ToString().ToUpper();
                string maLop = null;
                bool daTonTaiLop = dictLop.TryGetValue(tenLop, out maLop);
                if (daTonTaiLop == false)
                {
                    row[Col_MaLopGoc] = DBNull.Value;
                    row[Col_TrangThai] = Status_Error_LopSinhHoatChuaTonTai;

                    tenLop = row[Col_TenLopGoc].ToString();
                    if (lstUnknownClasses.Contains(tenLop) == false)
                        lstUnknownClasses.Add(tenLop);
                }
                else
                {
                    row[Col_MaLopGoc] = maLop;
                }
            }
            #endregion

            if (lstUnknownClasses.Count > 0)
            {
                return ImportPhaseDetect.Error_LopSinhHoatChuaTonTai;
            }
            #endregion

            #region 02. Đánh dấu sinh viên chưa tồn tại trong hệ thống/sinh viên bị sai tên lớp gốc
            int nUnknownMaSinhVien = 0;
            int nConflictTenLopSinhHoat = 0;
            using (var context = new QLHPEntities())
            {
                LopHocPhan oLopHocPhan = context.LopHocPhanDbSet.Where(e => e.MaLopHocPhan == lopHocPhan.MaLopHocPhan).SingleOrDefault();
                if (oLopHocPhan == null)
                    throw new Exception("Không tồn tại lớp học phần");
                var lstThongTinDangKy = oLopHocPhan.LopHocPhan_SinhVien;

                foreach (DataRow row in dt.Rows)
                {
                    string maSinhVien = row[Col_MaSinhVien].ToString();
                    string maLopGoc = row[Col_MaLopGoc].ToString();
                    SinhVien oSinhVien = (from sinhVien in context.SinhVienDbSet
                                          where sinhVien.MaSinhVien == maSinhVien
                                          select sinhVien).FirstOrDefault();
                    if (oSinhVien == null)
                    {
                        #region Sinh viên chưa tồn tại trong hệ thống
                        row[Col_TrangThai] = Status_Ready_TaoSVVaDangKy;
                        nUnknownMaSinhVien++;
                        #endregion
                    }
                    else if (oSinhVien.KC_MaLop != maLopGoc)
                    {
                        #region Sinh viên đã tồn tại trong hệ thống, nhưng lại ở lớp gốc khác so với khai báo trong Excel
                        row[Col_TrangThai] = Status_Error_DuLieuSinhVienKhongNhatQuan;
                        nConflictTenLopSinhHoat++;
                        #endregion
                    }
                    else
                    {
                        #region Kiểm tra xem đã tồn tại trong lớp học phần hay chưa
                        bool daCoTrongLopHocPhan = false;
                        foreach (var ttdk in lstThongTinDangKy)
                            if (ttdk.MaSinhVien == maSinhVien)
                            {
                                daCoTrongLopHocPhan = true;
                                break;
                            }

                        if (daCoTrongLopHocPhan)
                            row[Col_TrangThai] = Status_Warning_SinhVienDaDangKy;
                        else
                            row[Col_TrangThai] = Status_Ready_DangKy;
                        #endregion
                    }
                }
            }
            if (nConflictTenLopSinhHoat > 0)
            {
                return ImportPhaseDetect.Error_DuLieuSinhVienKhongNhatQuan;
            }
            #endregion

            dt.AcceptChanges();
            return ImportPhaseDetect.OK;
        }
    }
}
